package uk.ac.lkl.lpp.ui;



import java.awt.Font;
import java.awt.Point;

import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

//import uk.ac.lkl.lpp.model.*;

import uk.ac.lkl.lpp.dirtyListener;
import uk.ac.lkl.lpp.model.ldo.LearningEntity;


/**
 * An editor of learning entities.
 * 
 * Currently this editor is used for the editing of all learning entities.
 * 
 * @author Darren Pearce
 * @version $Revision: 635 $
 * @version $Date: 2008-03-04 01:30:21 +0000 (Tue, 04 Mar 2008) $
 * 
 */
public class LearningEntityEditor extends Box {
	/**
	 * 
	 */
	private static final long serialVersionUID = -858351452227438799L;

	
	/**
	 * single instance of this class 
	 */
	private static final LearningEntityEditor theLEE = new LearningEntityEditor();	
	
	/**
	 * key for title string
	 */
	public static final String TITLE_KEY = "LearningEntityEditor.title";
	
    /**
     * The learning entity that this editor is currently editing.
     * 
     */
    private LearningEntity entity;

    /**
     * The title field of this instance.
     * 
     */
    private JTextField titleField = new JTextField(14);

    /**
     * The description field of this instance.
     * 
     */
    private JTextArea descriptionField = new JTextArea(5, 20);
    
    /**
     * link field
     */
    private JTextField linkField = new JTextField(10);

    
    // so dialog can close
    /**
     * The array of action listeners listening to this instance.
     * 
     * Currently this facility is provided so that the editing dialog can close.
     * An action event is fired whether the ok or cancel button is clicked.
     * 
     * <p>
     * <b>Improvement:</b> Use EditingView.
     * </p>
     * 
     */
    private ArrayList<ActionListener> actionListeners = new ArrayList<ActionListener>();

    /**
     * get the singleton
     */
    public static final LearningEntityEditor getEditor() {
    	return theLEE;
    }
        
    /**
     * get the singleton, per an Entity to edit.
     */
    public static final LearningEntityEditor getEditor(LearningEntity entity) {
    	theLEE.setEntity(entity);
    	return theLEE;
    }
    
    /**
     * get the singleton dialog
     */
    public static final LearningEntityEditorDialog getEditorDialog() {
    	return LearningEntityEditorDialog.getDialog();
    }

    /**
     * get the singleton dialog
     */
    public static final LearningEntityEditorDialog getEditorDialog(Point location) {
    	return LearningEntityEditorDialog.getDialog(location);
    }
    
    /**
     * get the singleton dialog, per an Entity to edit.
     */
    public static final LearningEntityEditorDialog getEditorDialog(LearningEntity entity) {
    	LearningEntityEditorDialog.theLEEDialog.setEntity(entity);
    	return LearningEntityEditorDialog.theLEEDialog;
    }

    /**
     * get the singleton dialog, per an Entity to edit.
     */
    public static final LearningEntityEditorDialog getEditorDialog(LearningEntity entity, Point location) {
    	LearningEntityEditorDialog.theLEEDialog.setEntity(entity);
    	return LearningEntityEditorDialog.getDialog(location);
    }

    
    /**
     * Create a new instance for the given entity.
     * 
     * @param entity
     *            the entity
     * 
    private LearningEntityEditor(LearningEntity entity) {
    	this();
    	setEntity(entity);
    }
     */
    
    private LearningEntityEditor() {
    	super(BoxLayout.Y_AXIS);
    	
    	// --------- build the bits -------------------
        descriptionField.setLineWrap(true);
        descriptionField.setWrapStyleWord(true);
        // Uri: Is this yours or Darren's?
        //
        // hack so not a fixed width font
        // thanks to:
        // http://forum.java.sun.com/thread.jspa?threadID=519931&messageID=2484654
        Font defaultFont = UIManager.getFont("Label.font");
        descriptionField.setFont(defaultFont);

        JButton okButton = new JButton("Ok");
        okButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                updateData();
                fireActionPerformed(e);
            }
        });

        JButton cancelButton = new JButton("Cancel");
        cancelButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                fireActionPerformed(e);
            }
        });
        
        // --------------- now lay them out -------
        JScrollPane scrollPane = new JScrollPane(descriptionField);
        add(scrollPane);
        Box bb = new Box(BoxLayout.X_AXIS);
        bb.add(Messages.getJLabel(TITLE_KEY));
        bb.add(Box.createHorizontalGlue());
        add(bb);
        add(titleField);
        bb = new Box(BoxLayout.X_AXIS);
        bb.add(new JLabel("http://"));
        bb.add(linkField);
        add(bb);
        
        bb = new Box(BoxLayout.X_AXIS);
        bb.add(Box.createHorizontalStrut(6));
        bb.add(okButton);
        bb.add(Box.createHorizontalGlue());
        bb.add(cancelButton);
        bb.add(Box.createHorizontalStrut(6));
        add(bb);
    }
    
    public void setEntity(LearningEntity entity) {
        this.entity = entity;
        updateFields();
    }
    
    public void setVisible(boolean visible) {
    	if (visible) updateFields();
    	super.setVisible(visible);
    }


    /**
     * Update the fields with the information obtained from the learning entity.
     * 
     * This is called in response to a change event from the learning entity.
     * 
     */
    private void updateFields() {
        titleField.setText(entity.getTitle());
        descriptionField.setText(entity.getDescription());
        linkField.setText(entity.getLink());
    }


    /**
     * Update the learning entity with the information obtained from the fields.
     * 
     * This is called when the ok button is clicked.
     * 
     */
    private void updateData() {
        entity.setTitle(titleField.getText());
        entity.setDescription(descriptionField.getText());
        String l = linkField.getText();
        if (l != null && l.length() > 3) {
        	entity.setLink("http://"+l);
        }
    }


    /**
     * Add an action listener to this instance.
     * 
     * @param listener
     *            the listener to add
     * 
     */
    public void addActionListener(ActionListener listener) {
        actionListeners.add(listener);
    }


    /**
     * Fire an action event.
     * 
     * @param e
     *            the event
     * 
     */
    private void fireActionPerformed(ActionEvent e) {
        for (ActionListener listener : actionListeners)
            listener.actionPerformed(e);
    }
    
    /**
     * private class for editor dialog singleton. 
     * calling classes should use:
     * {@code 
     * 		LearningEntityEditor.getEditorDialog(LearningEntity e)
     * }
     * @author yish
     *
     */
    public static final class LearningEntityEditorDialog extends JDialog {
    	static final long serialVersionUID = 1L;
    	static final LearningEntityEditorDialog theLEEDialog = new LearningEntityEditorDialog(theLEE); 

    	LearningEntityEditor lee; 
    	
    	LearningEntityEditorDialog (LearningEntityEditor lee) {
    		this.lee = lee;
    		setAlwaysOnTop(true);
    		setContentPane(lee);
    		lee.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                	setVisible(false);
                }
            });
            pack();    		
    	}
    	
        public void setEntity(LearningEntity entity) {
            lee.setEntity(entity);
            setTitle("Edit " + entity.getType());
        }
        
        public static LearningEntityEditorDialog getDialog() {
        	return theLEEDialog;
        }

        public static LearningEntityEditorDialog getDialog(Point location) {
        	theLEEDialog.setLocation(location);
        	return theLEEDialog;
        }

    }

}
